package common.utils;

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 安全集合操作工具类
 * 提供对集合的安全操作，预防空指针异常
 */
public class SafeCollectionUtil {

    /**
     * 安全获取List中指定索引的元素
     * @param list 源列表
     * @param index 索引
     * @param <T> 元素类型
     * @return 指定索引的元素，如果列表为null或索引越界则返回null
     */
    public static <T> T getOrNull(List<T> list, int index) {
        if (list == null || index < 0 || index >= list.size()) {
            return null;
        }
        return list.get(index);
    }
    
    /**
     * 安全获取List中指定索引的元素，如果不存在则返回默认值
     * @param list 源列表
     * @param index 索引
     * @param defaultValue 默认值
     * @param <T> 元素类型
     * @return 指定索引的元素，如果列表为null或索引越界则返回默认值
     */
    public static <T> T getOrDefault(List<T> list, int index, T defaultValue) {
        T value = getOrNull(list, index);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 安全获取Map中指定键的值
     * @param map 源Map
     * @param key 键
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 指定键的值，如果Map为null或键不存在则返回null
     */
    public static <K, V> V getOrNull(Map<K, V> map, K key) {
        if (map == null) {
            return null;
        }
        return map.get(key);
    }
    
    /**
     * 安全获取Map中指定键的值，如果不存在则返回默认值
     * @param map 源Map
     * @param key 键
     * @param defaultValue 默认值
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 指定键的值，如果Map为null或键不存在则返回默认值
     */
    public static <K, V> V getOrDefault(Map<K, V> map, K key, V defaultValue) {
        if (map == null) {
            return defaultValue;
        }
        return map.getOrDefault(key, defaultValue);
    }
    
    /**
     * 安全过滤集合，移除null元素和不满足条件的元素
     * @param collection 源集合
     * @param predicate 过滤条件
     * @param <T> 元素类型
     * @return 过滤后的新列表，如果源集合为null则返回空列表
     */
    public static <T> List<T> safeFilter(Collection<T> collection, Predicate<T> predicate) {
        if (collection == null) {
            return new ArrayList<>();
        }
        return collection.stream()
                .filter(Objects::nonNull)
                .filter(predicate)
                .collect(Collectors.toList());
    }
    
    /**
     * 安全映射集合，处理null元素，并转换为新类型
     * @param collection 源集合
     * @param mapper 映射函数
     * @param <T> 源元素类型
     * @param <R> 目标元素类型
     * @return 映射后的新列表，如果源集合为null则返回空列表
     */
    public static <T, R> List<R> safeMap(Collection<T> collection, Function<T, R> mapper) {
        if (collection == null) {
            return new ArrayList<>();
        }
        return collection.stream()
                .filter(Objects::nonNull)
                .map(mapper)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    
    /**
     * 安全合并多个集合
     * @param collections 要合并的集合数组
     * @param <T> 元素类型
     * @return 合并后的新列表
     */
    @SafeVarargs
    public static <T> List<T> safeMerge(Collection<T>... collections) {
        List<T> result = new ArrayList<>();
        if (collections == null) {
            return result;
        }
        
        for (Collection<T> collection : collections) {
            if (collection != null) {
                result.addAll(collection);
            }
        }
        
        return result;
    }
    
    /**
     * 安全获取集合的第一个元素
     * @param collection 源集合
     * @param <T> 元素类型
     * @return 第一个元素，如果集合为null或空则返回null
     */
    public static <T> T getFirstOrNull(Collection<T> collection) {
        if (OptionalUtil.isEmpty(collection)) {
            return null;
        }
        
        return collection.iterator().next();
    }
    
    /**
     * 安全获取集合的第一个元素，如果不存在则返回默认值
     * @param collection 源集合
     * @param defaultValue 默认值
     * @param <T> 元素类型
     * @return 第一个元素，如果集合为null或空则返回默认值
     */
    public static <T> T getFirstOrDefault(Collection<T> collection, T defaultValue) {
        T first = getFirstOrNull(collection);
        return first != null ? first : defaultValue;
    }
    
    /**
     * 创建不可变的空列表
     * @param <T> 元素类型
     * @return 不可变的空列表
     */
    public static <T> List<T> emptyList() {
        return Collections.emptyList();
    }
    
    /**
     * 创建不可变的空Map
     * @param <K> 键类型
     * @param <V> 值类型
     * @return 不可变的空Map
     */
    public static <K, V> Map<K, V> emptyMap() {
        return Collections.emptyMap();
    }
    
    /**
     * 创建不可变的空Set
     * @param <T> 元素类型
     * @return 不可变的空Set
     */
    public static <T> Set<T> emptySet() {
        return Collections.emptySet();
    }
} 